﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	SqlEntityMapper.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

#define FAST_MAPPER

using Smart.Common.Entities.Mapper;

namespace Smart.Common.Entities
{
	public class SqlEntityMapper : EntityMapper
	{
		public static SqlEntityMapper Current = new SqlEntityMapper();

#if FAST_MAPPER
		public override MapperClassBuilderConfig GetConfig()
		{
			var config = new MapperClassBuilderConfig
							{
								Usings = "using Smart.Common.Entities;",
								SourceType = "SqlItem"
							};

			config.FillTempls[FieldMappingType.Identifier] = "e.{0} = Identifier.Empty;";
			config.FillTempls[FieldMappingType.String] = "e.{0} = null;";
			config.FillTempls[FieldMappingType.DateTime] = "e.{0} = DateTime.MinValue;";
			config.FillTempls[FieldMappingType.Int] = "e.{0} = 0;";
			config.FillTempls[FieldMappingType.Double] = "e.{0} = 0;";
			//config.FillTempls[FieldMappingType.Decimal] = "e.{0} = 0;";
			config.FillTempls[FieldMappingType.Bool] = "e.{0} = false;";
			config.FillTempls[FieldMappingType.Lookup] = "e.{0} = new LookupValue(Identifier.Empty);";
			config.FillTempls[FieldMappingType.LookupMulti] = "e.{0} = throw new NotSupportedException();";
			config.FillTempls[FieldMappingType.User] = "e.{0} = new UserValue(Identifier.Empty);";
			config.FillTempls[FieldMappingType.UserMulti] = "e.{0} = throw new NotSupportedException();";
			config.FillTempls[FieldMappingType.Link] = "e.{0} = new LinkValue(null, null);";
			config.FillTempls[FieldMappingType.ChoiceMulti] = "e.{0} = throw new NotSupportedException();";

			config.PreLoad = "\t\t\tstring tmp;\t\t\tint tmpInt = 0;";
			config.LoadTempls[FieldMappingType.Identifier] = "e.{0} = new Identifier(s.Values.SafeGet(\"{1}\", null));";
			config.LoadTempls[FieldMappingType.String] = "e.{0} = (string)s.Values.SafeGet(\"{1}\", null);";
			config.LoadTempls[FieldMappingType.DateTime] = "e.{0} = s.Values.SafeGetDT(\"{1}\", DateTime.MinValue);";
			config.LoadTempls[FieldMappingType.Int] = "e.{0} = s.Values.SafeGetInt(\"{1}\", 0);";
			config.LoadTempls[FieldMappingType.Double] = "e.{0} = s.Values.SafeGetDbl(\"{1}\", 0);";
			//config.LoadTempls[FieldMappingType.Decimal] = "e.{0} = new Decimal(s.Values.SafeGetDbl(\"{1}\", 0));";
			config.LoadTempls[FieldMappingType.Bool] = "e.{0} = (s.Values.SafeGetInt(\"{1}\", 0) == 1) ? true : false;";
			config.LoadTempls[FieldMappingType.Lookup] = "tmpInt = s.Values.SafeGetInt(\"{1}\", 0); e.{0} = (tmpInt == 0 ? new LookupValue(Identifier.Empty) : new LookupValue(tmpInt));";
			config.LoadTempls[FieldMappingType.LookupMulti] = "throw new NotSupportedException();";
			config.LoadTempls[FieldMappingType.User] = "tmpInt = s.Values.SafeGetInt(\"{1}\", 0); e.{0} = (tmpInt == 0 ? new UserValue(Identifier.Empty) :  new UserValue(tmpInt));";
			config.LoadTempls[FieldMappingType.UserMulti] = "throw new NotSupportedException();";
			config.LoadTempls[FieldMappingType.Link] = "tmp = (string)s.Values.SafeGet(\"{1}\", null); e.{0} = (tmp.IsNullOrEmpty() ? new LinkValue(null, null) : new SPFieldUrlValue(tmp).CvtL());";
			config.LoadTempls[FieldMappingType.ChoiceMulti] = "throw new NotSupportedException();";

			config.SaveTempls[FieldMappingType.Identifier] = "s.Values[\"{1}\"] = e.{0}.Int;";
			config.SaveTempls[FieldMappingType.String] = "s.Values[\"{1}\"] = e.{0};";
			config.SaveTempls[FieldMappingType.DateTime] = "s.Values[\"{1}\"] = (e.{0} == DateTime.MinValue ? null : (object)e.{0});";
			config.SaveTempls[FieldMappingType.Int] = "s.Values[\"{1}\"] = e.{0};";
			config.SaveTempls[FieldMappingType.Double] = "s.Values[\"{1}\"] = e.{0};";
			//config.SaveTempls[FieldMappingType.Decimal] = "s.Values[\"{1}\"] = e.{0};";
			config.SaveTempls[FieldMappingType.Bool] = "s.Values[\"{1}\"] = e.{0} ? 1 : 0;";
			config.SaveTempls[FieldMappingType.Lookup] = "s.Values[\"{1}\"] = e.{0}.ID.Int;";
			config.SaveTempls[FieldMappingType.LookupMulti] = "throw new NotSupportedException();";
			config.SaveTempls[FieldMappingType.User] = "s.Values[\"{1}\"] = e.{0}.ID.Int;";
			config.SaveTempls[FieldMappingType.UserMulti] = "throw new NotSupportedException();";
			config.SaveTempls[FieldMappingType.Link] = "s.Values[\"{1}\"] = e.{0}.ToString();";
			config.SaveTempls[FieldMappingType.ChoiceMulti] = "throw new NotSupportedException();";

			return config;
		}
#else
	/// <summary>
	/// Load entity values from source
	/// </summary>
		public override bool LoadEntity(object source, Entity entity)
		{
			var s = source as SqlItem;

			if (s == null)
				throw new ArgumentException();

			var et = entity.GetType();

			var typeName = et.FullName;

			var mapping = ReadCache(typeName, et);

			foreach (var fmi in mapping)
			{
				if (fmi.Direction == FieldMappingDirection.Out)
					continue;

				switch (fmi.MappingType)
				{
					case FieldMappingType.Identifier:
						fmi.Property.SetValue(entity, s.Values.SafeGet(fmi.FieldName, Identifier.Empty), null);
						break;

					case FieldMappingType.String:
						fmi.Property.SetValue(entity, (string)s.Values.SafeGet(fmi.FieldName, string.Empty), null);
						break;

					case FieldMappingType.DateTime:
						fmi.Property.SetValue(entity, s.Values.SafeGetDT(fmi.FieldName, DateTime.MinValue), null);
						break;

					case FieldMappingType.Int:
						fmi.Property.SetValue(entity, s.Values.SafeGetInt(fmi.FieldName, 0), null);
						break;

					case FieldMappingType.Double:
						fmi.Property.SetValue(entity, s.Values.SafeGetDbl(fmi.FieldName, 0), null);
						break;

					case FieldMappingType.Bool:
						fmi.Property.SetValue(entity, (bool)s.Values.SafeGet(fmi.FieldName, false), null);
						break;

					case FieldMappingType.Lookup:
						fmi.Property.SetValue(entity, s.Values.SafeGetInt(fmi.FieldName, 0), null);
						break;

					case FieldMappingType.LookupMulti:
						throw new NotSupportedException();

					case FieldMappingType.User:
						fmi.Property.SetValue(entity, (string)s.Values.SafeGet(fmi.FieldName, string.Empty), null);
						break;

					case FieldMappingType.UserMulti:
						throw new NotSupportedException();

					case FieldMappingType.Link:
						fmi.Property.SetValue(entity, (string)s.Values.SafeGet(fmi.FieldName, string.Empty), null);
						break;

					case FieldMappingType.ChoiceMulti:
						throw new NotSupportedException();

					default:
						throw new NotSupportedException();
				}
			}

			return true;
		}

		/// <summary>
		/// Save entity values to source
		/// </summary>
		public override bool SaveEntity(Entity entity, object source)
		{
			throw new NotImplementedException();
		}
#endif
	}
}